package com.javafactroy.kunlong.data.web;


import cn.hutool.core.util.StrUtil;
import com.javafactroy.kunlong.base.dto.TQueryParam;
import com.javafactroy.kunlong.base.model.ReturnPageInfo;
import com.javafactroy.kunlong.client.feign.dto.PageInfoDto;
import com.javafactroy.kunlong.common.core.controller.BaseController;
import com.javafactroy.kunlong.data.iface.IGeneralService;
import com.javafactroy.kunlong.data.iface.IWebService;
import com.javafactroy.kunlong.common.utils.CommonUtils;
import com.javafactroy.kunlong.common.utils.ExcelExportDto;
import com.javafactroy.kunlong.common.utils.ExcelExportService;
import com.javafactroy.kunlong.common.utils.ExcelImportService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

@Slf4j
public abstract class WebService<T extends PageInfoDto, SEVICE extends IGeneralService> extends BaseController implements IWebService<T> {

    @Autowired
    protected ExcelImportService excelImportService;

    @Autowired
    protected SEVICE service;

    @Autowired
    protected ExcelExportService excelExportService;

    @PostMapping("save")
    @ResponseBody
    @ApiOperation("保存")
    public int save(@RequestBody T entity) {
        return service.save(entity);
    }

    @PostMapping("saveBatch")
    @ResponseBody
    @ApiOperation("批量保存")
    public int saveBatch(@RequestBody List<T> entities) {

        return service.saveBatch(entities);
    }


    @PostMapping("insert")
    @ResponseBody
    @ApiOperation("新增")
    public int insert(@RequestBody T entity) {
        return service.insert(entity);
    }

    @PostMapping("update")
    @ResponseBody
    @ApiOperation("更新")
    public int update(@RequestBody T entity) {
        return service.update(entity);
    }

    @PostMapping("updateNotNull")
    @ResponseBody
    @ApiOperation("更新非空字段")
    public int updateNotNull(@RequestBody T entity) {
        return service.updateNotNull(entity);
    }


    @DeleteMapping("deleteBy")
    @ResponseBody
    @ApiOperation("条件删除")
    public int deleteBy(@RequestBody T entity) {
        return service.deleteBy(entity);
    }

    @DeleteMapping("deleteByPkey")
    @ResponseBody
    @ApiOperation("根据主键删除（单主键）")
    public int deleteByPkey(@RequestParam("id") Long id) {
        return service.deleteByPkey(id);
    }

    @DeleteMapping("deleteByPkeys")
    @ResponseBody
    @ApiOperation("根据多主键删除")
    public int deleteByPkeys(@RequestBody T entity) {
        return service.deleteByPkeys(entity);
    }


    @PostMapping("selectCount")
    @ResponseBody
    @ApiOperation("统计个数")
    public int selectCount(@RequestBody T entity) {
        return service.selectCount(entity);
    }

    @GetMapping("selectByPkey")
    @ResponseBody
    @ApiOperation("根据主键查询")
    public T selectByPkey(@RequestParam("id") Long id) {
        return (T) service.selectByPkey(id);
    }

    @Override
    public T selectByPkeys(T t) {
        return (T) service.selectByPkeys(t);
    }

    @PostMapping("select")
    @ResponseBody
    @ApiOperation("条件查询")
    public List<T> select(@RequestBody T entity) {

        return service.select(entity);
    }

    // @PostMapping("selectAll")
    //   @ResponseBody
    @ApiOperation("查询全部")
    public List<T> selectAll() {

        return service.selectAll();
    }

    @PostMapping("queryParam")
    @ResponseBody
    @ApiOperation("分页查询")
    public ReturnPageInfo<T> queryParam(@RequestBody TQueryParam<T> queryParam) {

        log.info("queryParam = {}", CommonUtils.toJSONString(queryParam));
        return service.queryParam(queryParam);
    }

    @PostMapping("query")
    @ResponseBody
    @ApiOperation("分页查询")
    public ReturnPageInfo<T> query(@RequestBody T entity) {

        ReturnPageInfo pageInf = service.query(entity);
        log.info("web query={}", CommonUtils.toJSONString(pageInf));
        return pageInf;
    }

    @PostMapping("count")
    @ResponseBody
    @ApiOperation("count个数")
    public long count(@RequestBody T entity) {

        return service.count(entity);
    }

    @ApiOperation("导出")
    @PostMapping("exportParam")
    public void exportParam(HttpServletResponse response, @RequestBody TQueryParam<T> param) throws IOException {

        ReturnPageInfo<T> apiPageInfo = service.queryParam(param);
        log.info("queryParam = {}", CommonUtils.toJSONString(param));
        log.info("size = {}, apiPageInfo = {}", apiPageInfo.getList().size(), CommonUtils.toJSONString(apiPageInfo));

        String sheetName = param.getClass().getSimpleName();

        ExcelExportDto<T> excelExportDto = new ExcelExportDto<>();
        excelExportDto.setFileName(StrUtil.format("Export{}{}", sheetName, CommonUtils.today()));
        excelExportDto.setSheetName(sheetName);
        excelExportDto.setRecords(apiPageInfo.getList());
        log.info("export file = {}", excelExportDto.getFileName());
        excelExportService.export(response, excelExportDto);

    }

    @ApiOperation("导出xlsx")
    @PostMapping("export")
    public void export(HttpServletResponse response, @RequestBody T param) throws IOException {

        ReturnPageInfo<T> apiPageInfo = service.query(param);
        log.info("export={}", param);

        String sheetName = param.getClass().getSimpleName();

        ExcelExportDto<T> excelExportDto = new ExcelExportDto<>();
        excelExportDto.setFileName(StrUtil.format("Export{}{}", sheetName, CommonUtils.today()));
        excelExportDto.setSheetName(sheetName);
        excelExportDto.setRecords(apiPageInfo.getList());
        log.info("export file = {}", excelExportDto.getFileName());
        excelExportService.export(response, excelExportDto);

    }

    public class GeneralClass<T> {
        private Class<T> type;

        public GeneralClass() {
            Type superClass = getClass().getGenericSuperclass();
            Type[] typeArgs = ((ParameterizedType) superClass).getActualTypeArguments();
            this.type = (Class<T>) typeArgs[0];
        }

        public Class<T> getType() {
            return type;
        }

    }

//    @PostMapping(value = "/importXls")
//    public void importXls(@RequestPart(value = "file") MultipartFile file) throws IOException {
//        GeneralClass<T> generalClass = new GeneralClass<>();
//        excelImportService.importData( file ,null);
//
//
//    }

}
